#include "MoveSystem.h"
#include <algorithm>

static Vec2i dirVec(Direction d) {
    if (d==Direction::Up) return {0,-1};
    if (d==Direction::Down) return {0,1};
    if (d==Direction::Left) return {-1,0};
    return {1,0};
}

static bool isWall(const Level& level, const Vec2i& p) {
    if (p.x<0 || p.y<0 || p.x>=level.width() || p.y>=level.height()) return true;
    return level.tileAt(p.x,p.y)==Tile::Wall;
}

static bool hasBox(const GameState& s, const Vec2i& p) {
    for (auto& b : s.boxes) if (b==p) return true;
    return false;
}

static void moveBox(GameState& s, const Vec2i& from, const Vec2i& to) {
    for (auto& b : s.boxes) if (b==from) { b=to; return; }
}

bool MoveSystem::move(const Level& level, GameState& state, Direction dir) {
    Vec2i d = dirVec(dir);
    Vec2i np = { state.player.x + d.x, state.player.y + d.y };
    if (isWall(level,np)) return false;
    if (hasBox(state,np)) {
        Vec2i nb = { np.x + d.x, np.y + d.y };
        if (isWall(level,nb) || hasBox(state,nb)) return false;
        moveBox(state,np,nb);
    }
    state.player = np;
    return true;
}